import argparse
import json
import os
import sys
import threading
import time
from functools import lru_cache
from typing import Literal
import requests
from dotenv import load_dotenv
from loguru import logger
from pydantic import computed_field
from pydantic_settings import BaseSettings
from Util.EncoderUtil import encode, key_bytes, decode


class SystemUserInfo():
    # username: str = '20220808354'
    # password: str = '123456789'
    username: str = '20230806322'
    password: str = '@Sjt15990438823'
    token: str = ''

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.token = None
        self._lock = threading.Lock()
        self._start_token_refresh()

    def _start_token_refresh(self):
        def refresh():
            while True:
                self.update_token()
                time.sleep(60 * 60)  # 每60分钟刷新一次

        t = threading.Thread(target=refresh, daemon=True)
        t.start()

    def get_authorization(self):
        # 使用当前时间戳
        timestamp = int(time.time() * 1000)
        t = f'{{"token":"","platform":3,"version":"2.0.5","device":"FAAE6E21-013F-42D1-B722-599DE3DC340F","timestamp":{timestamp}}}'
        return encode(t, key_bytes)

    def update_token(self):
        access = f'{{"schoolCode":11505,"code":"{self.username}","password":"{self.password}"}}'
        params = encode(access)
        try:
            # 发起请求
            response = requests.get(
                "https://ekta.jjvu.jx.cn/api/app/client/v1/token",
                params={"params": params},
                headers={"Authorization": self.get_authorization()}
            )
            # 解密响应
            decrypted_string = decode(response.text)
            if not decrypted_string:
                raise Exception("解密结果为空字符串")
            # 解析JSON
            decrypted_json = json.loads(decrypted_string)
            # 提取token
            new_token = decrypted_json["data"]["access_token"]
            if not new_token:
                raise Exception("未能从解密后的数据中提取到 access_token")
            else:
                logger.info(f'获取系统管理员token成功 ')

        except Exception as e:
            logger.error(f"getToken 函数内部错误: {e}")
            return None
        logger.info(f'定时更新token成功  {str(new_token)[0:10]}.....')
        with self._lock:
            self.token = new_token

    def get_token(self):
        with self._lock:
            return self.token

    pass


class DataBaseSettings(BaseSettings):
    """
    数据库配置
    """
    db_type: Literal['mysql', 'postgresql'] = 'mysql'
    db_host: str = '127.0.0.1'
    db_port: int = 3306
    db_username: str = 'root'  #linux -->  yirc99
    db_password: str = '123456'#linux -->  zhu020929
    db_database: str = 'two'
    db_echo: bool = True
    db_max_overflow: int = 10
    db_pool_size: int = 50
    db_pool_recycle: int = 3600
    db_pool_timeout: int = 30

    @computed_field
    @property
    def sqlglot_parse_dialect(self) -> str:
        if self.db_type == 'postgresql':
            return 'postgres'
        return self.db_type


class GetConfig:
    """
    获取配置
    """

    def __init__(self):
        self.parse_cli_args()

    @lru_cache()
    def get_database_config(self):
        """
        获取数据库配置
        """
        # 实例化数据库配置模型
        return DataBaseSettings()

    @staticmethod
    def parse_cli_args():
        """
        解析命令行参数
        """
        if 'uvicorn' in sys.argv[0]:
            # 使用uvicorn启动时，命令行参数需要按照uvicorn的文档进行配置，无法自定义参数
            pass
        else:
            # 使用argparse定义命令行参数
            parser = argparse.ArgumentParser(description='命令行参数')
            parser.add_argument('--env', type=str, default='', help='运行环境')
            # 解析命令行参数
            args = parser.parse_args()
            # 设置环境变量，如果未设置命令行参数，默认APP_ENV为dev
            os.environ['APP_ENV'] = args.env if args.env else 'dev'
        # 读取运行环境
        run_env = os.environ.get('APP_ENV', '')
        # 运行环境未指定时默认加载.env.dev
        env_file = '.env.dev'
        # 运行环境不为空时按命令行参数加载对应.env文件
        if run_env != '':
            env_file = f'.env.{run_env}'
        # 加载配置
        load_dotenv(env_file)


# 实例化获取配置类
get_config = GetConfig()

# 数据库配置
DataBaseConfig = get_config.get_database_config()
SystemUserInfo = SystemUserInfo()
